# coding: UTF-8
# @Date    ：2024/10/14 18:23 
# @File    : demo_1.py
# :Author:  fum
import json
import os
import threading

import psutil

from configs import APP
from . import api

# 定义 Flask-RESTx 的模型
memory_model = api.model('Memory', {
    'description': fields.String(description='内存信息描述'),
    'total': fields.String(description='总内存'),
    'used': fields.String(description='已用内存'),
    'usage': fields.String(description='内存使用率')
})

disk_model = api.model('Disk', {
    'description': fields.String(description='磁盘信息描述'),
    'total': fields.String(description='总磁盘空间'),
    'used': fields.String(description='已用磁盘空间'),
    'usage': fields.String(description='磁盘使用率')
})

process_model = api.model('Process', {
    'pid': fields.Integer(description='进程ID'),
    'name': fields.String(description='进程名称'),
    'num_threads': fields.Integer(description='线程数')
})

# 定义响应模型
system_info_model = api.model('SystemInfoResponse', {
    'memory': fields.Nested(memory_model),
    'disk': fields.Nested(disk_model),
    'processes': fields.List(fields.Nested(process_model))
})


@api.route('/')
class SystemInfo(Resource):

    @api.marshal_with(system_info_model)
    def get(self):
        """返回系统内存、磁盘存储和进程/线程信息及描述。"""
        # 获取系统内存信息
        memory_info = psutil.virtual_memory()
        total_memory = round(memory_info.total / (1024 ** 3), 2)
        used_memory = round(memory_info.used / (1024 ** 3), 2)
        memory_usage = round(memory_info.percent, 2)

        # 获取磁盘存储信息
        disk_info = psutil.disk_usage('/')
        total_disk = round(disk_info.total / (1024 ** 3), 2)
        used_disk = round(disk_info.used / (1024 ** 3), 2)
        disk_usage = round(disk_info.percent, 2)

        # 获取进程和线程信息
        process_info = []
        for proc in psutil.process_iter(['pid', 'name', 'num_threads']):
            process_info.append({
                'pid': proc.info['pid'],
                'name': proc.info['name'],
                'num_threads': proc.info['num_threads']
            })

        # 构造返回结果
        response = {
            'memory': {
                'description': '总内存、已用内存和使用率（GB）',
                'total': f"{total_memory} GB",
                'used': f"{used_memory} GB",
                'usage': f"{memory_usage}%"
            },
            'disk': {
                'description': '总磁盘空间、已用磁盘空间和使用率（GB）',
                'total': f"{total_disk} GB",
                'used': f"{used_disk} GB",
                'usage': f"{disk_usage}%"
            },
            'processes': process_info
        }

        return response


@api.route("/health")
class Health(Resource):
    def get(self):
        return Response(
            json.dumps({"pid": os.getpid(), "status": "ok", "version": APP.config["version"]}),
            status=200,
            content_type="application/json",
        )


@api.route("/threads")
class Threads(Resource):
    def get(self):
        num_threads = threading.active_count()
        threads = threading.enumerate()

        thread_list = []
        for thread in threads:
            thread_name = thread.name
            thread_id = thread.ident
            is_alive = thread.is_alive()

            thread_list.append(
                {
                    "name": thread_name,
                    "id": thread_id,
                    "is_alive": is_alive,
                }
            )

        return {
            "pid": os.getpid(),
            "thread_num": num_threads,
            "threads": thread_list,
        }


@api.route("/db-pool-stat")
class DbPoolStat(Resource):
    def get(self):
        engine = APP.config.get("db").engine
        return {
            "pid": os.getpid(),
            "pool_size": engine.pool.size(),
            "checked_in_connections": engine.pool.checkedin(),
            "checked_out_connections": engine.pool.checkedout(),
            "overflow_connections": engine.pool.overflow(),
            "connection_timeout": engine.pool.timeout(),
            "recycle_time": APP.config.get("db").engine.pool._recycle,
        }
